#pragma once
#include <unordered_set>
#include "Common.hpp"
#include <string>

class Command
{
public:
    Command()
    {
        // 允许调用的命令
        _white_list.emplace("ls -l");
        _white_list.emplace("pwd");
        _white_list.emplace("tree");
        _white_list.emplace("whoami");
        _white_list.emplace("touch");
    }
    void Excute(int sockfd, const InetAddr& client, const std::string& command)
    {
        if(!_white_list.count(command))
        {
            std::string info = "非法的命令! [" + command + "]";
            LOG(LogLevel::ERROR) << info;
            write(sockfd, info.c_str(), info.size());
            return;
        }

        FILE *fp = popen((command + " 2>&1").c_str(), "r");
        if(fp == nullptr)
        {
            std::string info = std::string("popen: 创建子进程或管道失败! ") + strerror(errno);
            LOG(LogLevel::ERROR) << info;
            write(sockfd, info.c_str(), info.size());
            return;
        }

        char buffer[BUFFER_SIZE];
        std::string result;
        while(fgets(buffer, sizeof(buffer), fp))
        {
            result += buffer;
        }
        pclose(fp);
        ssize_t size = write(sockfd, result.c_str(), result.size());
        if (size == -1)
        {
            LOG(LogLevel::ERROR) << "write: [" << client.Info() << "]写入数据时出错! " << std::strerror(errno);
            exit(WRITE_ERROR);
        }
    }
private:
    std::unordered_set<std::string> _white_list;
};